package aTurk2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class HumanPricing implements Parameters{

	/**
	 * @param args
	 */
	private ArrayList<Problem> problemArr;
	private StringBuilder sb;
	public static void main(String[] args) throws Exception{
		HumanPricing human=new HumanPricing();
		Random randGen=new Random();
		for(int i=0;i<PROBLEM_SIZE;++i){
			int j=i+1;
			String path="servers/7/"+j+".csv";
			human.loadData(path);
			human.addHuman(randGen);
			int humanNewId=human.shuffle(randGen);
			human.save(j, humanNewId);
		}
	}
	public void save(int j, int humanNewId) throws Exception{
		String strDirectoy ="servers/human/"+j;
		// Create servers directory
		(new File(strDirectoy)).mkdirs();

		String strDirect2="servers/human/srv";
		(new File(strDirect2)).mkdirs();
		String filename2=strDirect2+"/"+j+".srv";
		PrintWriter srvWrite=new PrintWriter(filename2);
		for(int i=0;i<problemArr.size();i++){
			int k=i+1;
			String filename=strDirectoy+"/"+k+".csv";
			PrintWriter pw=new PrintWriter(filename);
			String s1=problemArr.get(i).toExcelFormat();
			pw.write(s1);
			pw.close();
			
			srvWrite.append(problemArr.get(i).toSpecialFormat());
			srvWrite.append("\n");
		}
		srvWrite.close();
		
		//save the: problem number,human number,revenue,money spent
		if(j==1){
			sb=new StringBuilder();
			sb.append("problem number,human number,revenue,money spent");
			sb.append("\n");
		}
		
		String str=j+","+humanNewId+","+problemArr.get(humanNewId-1).revenue+","+problemArr.get(humanNewId-1).moneySpent;
		sb.append(str);
		sb.append("\n");
		if(j==PROBLEM_SIZE){
			String path="servers/human/humanInfo.csv";
			PrintWriter optimalWrite=new PrintWriter(path);
			optimalWrite.append(sb.toString());
			optimalWrite.close();
		}
	}
	private int shuffle(Random rndGen){
		int location=rndGen.nextInt(problemArr.size());
		problemArr.get(location).id=problemArr.size();
		problemArr.get(problemArr.size()-1).id=location+1;
		Collections.sort(problemArr, new IdComperator());
		return (location+1);
	}
	
	private void loadData(String path) throws Exception{
		problemArr=new ArrayList<Problem>();
		BufferedReader in=new BufferedReader(new FileReader(path));
		String line=in.readLine();
		while(line!=null){
			problemArr.add(new Problem(line));
			line=in.readLine();
		}
		in.close();
	}
	private void addHuman(Random randGen){
		int _cost=randGen.nextInt(MAX_QUERY_TIME)+1;	//1-MAX_QUERY_TIME
		Problem hum=getHum(problemArr.size()+1, _cost);
		problemArr.add(hum);
	}
	private  Problem getHum(int id,int _cost){
		Collections.sort(problemArr, new ExpAndCostComperator());
		int lastIndex=problemArr.size()-1;
		//getting the last problem
		Problem pLast=problemArr.remove(lastIndex);
		lastIndex=problemArr.size()-1;
		//getting the problem before the last
		Problem pBeforeLast=problemArr.remove(lastIndex);
		
		//opening the two stores with the highest Exp+cost
		int accCost=pLast.cost+pBeforeLast.cost;
		int realValueLast=pLast.realVal;
		int realValueBeforeLast=pBeforeLast.realVal;
		//indicates if the last store has the minimum real price
		boolean last_store=true;
		int minRealVal=realValueLast;
		if(realValueBeforeLast<minRealVal){
			minRealVal=realValueBeforeLast;
			last_store=false;
		}
		
		//if true: there is no reason to reveal the two stores, we'll reveal just one store's real value
		if((int)(minRealVal*PERCENTAGE_UNDER)-accCost-_cost<1){
			//do not reveal any of the stores
			if((int)(realValueBeforeLast*PERCENTAGE_UNDER)-accCost-_cost<1&&(int)(realValueLast*PERCENTAGE_UNDER)-accCost-_cost<1){
				problemArr.add(pBeforeLast);
				problemArr.add(pLast);
				//sorting the probArr by Ids
				Collections.sort(problemArr, new IdComperator());
				
				//creating our store
				Problem humanProb=new Problem(id, 0, accCost+_cost+1);
				humanProb.revenue=1;
				humanProb.moneySpent=-accCost;
				return humanProb;
			}
			//do not reveal the last stores price
			if(last_store){
				problemArr.add(pLast);
				problemArr.add(new Problem(pBeforeLast.id, 0, realValueBeforeLast));
				//sorting the probArr by Ids
				Collections.sort(problemArr, new IdComperator());
				
				//creating our store
				Problem humanProb=new Problem(id, 0, (int)(realValueBeforeLast*PERCENTAGE_UNDER));
				humanProb.revenue=(int)(realValueBeforeLast*PERCENTAGE_UNDER)-accCost-_cost;
				humanProb.moneySpent=-accCost;
				return humanProb;
			}else{
				//do not reveal the real price of the before last store
				problemArr.add(pBeforeLast);
				problemArr.add(new Problem(pLast.id, 0, realValueLast));
				//sorting the probArr by Ids
				Collections.sort(problemArr, new IdComperator());
				
				//creating our store
				Problem humanProb=new Problem(id, 0, (int)(realValueLast*PERCENTAGE_UNDER));
				humanProb.revenue=(int)(realValueLast*PERCENTAGE_UNDER)-accCost-_cost;
				humanProb.moneySpent=-accCost;
				return humanProb;
			}
		}
		//inserting the two stores open
		problemArr.add(new Problem(pLast.id, 0, realValueLast));
		problemArr.add(new Problem(pBeforeLast.id, 0, realValueBeforeLast));
		
		//sorting the probArr by Ids
		Collections.sort(problemArr, new IdComperator());
		
		//creating our store
		Problem humanProb=new Problem(id, 0, (int)(minRealVal*PERCENTAGE_UNDER));
		humanProb.revenue=(int)(minRealVal*PERCENTAGE_UNDER)-accCost-_cost;
		humanProb.moneySpent=-accCost;
		return humanProb;
	}

}
